package com.sss.gsb.util;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sss.gsb.client.grid.RowModel;
import com.sss.gsb.message.schemas.BondsManRequest;
import com.sss.gsb.message.schemas.BondsmanType;
import com.sss.gsb.message.schemas.DeadmanRequest;
import com.sss.gsb.message.schemas.DeadmanType;
import com.sss.gsb.message.schemas.InsuranceRequest;
import com.sss.gsb.message.schemas.InsuranceType;
import com.sss.gsb.message.schemas.LoanAccountClosedRequest;
import com.sss.gsb.message.schemas.LoanAccountClosedType;
import com.sss.gsb.message.schemas.LoanRequest;
import com.sss.gsb.message.schemas.LoanType;
import com.sss.gsb.message.schemas.ObjectFactory;
import com.sss.gsb.orm.model.BondsMan;
import com.sss.gsb.orm.model.Customer;
import com.sss.gsb.orm.model.DeadMan;
import com.sss.gsb.orm.model.Insurance;
import com.sss.gsb.orm.model.Loan;
import com.sss.gsb.orm.model.LoanAccountClosed;
import com.sss.gsb.service.LoadParameter;

public abstract class SchemaConvertionUtils {
	private static Logger log = LoggerFactory
			.getLogger(SchemaConvertionUtils.class);

	private static ObjectFactory schemaTypeFactory = new ObjectFactory();

	/**
	 * convert java.util.Date to XMLGregorianCalendar
	 * 
	 * @param java
	 *            .util.Date
	 * @return
	 */
	private static XMLGregorianCalendar toXMLGregorianCalendar(Date d) {
		if (d == null) {
			return null;
		}
		Calendar c = new GregorianCalendar();
		c.setTime(d);
		int day = c.get(Calendar.DAY_OF_MONTH);
		int month = c.get(Calendar.MONTH) + 1;
		int year = c.get(Calendar.YEAR);
		int timezone = c.getTimeZone().getOffset(d.getTime())
				/ (60 * 60 * 1000);
		try {
			return DatatypeFactory.newInstance().newXMLGregorianCalendarDate(
					year, month, day, timezone);
		} catch (DatatypeConfigurationException e) {
			log.error(e.getMessage(), e);
		}
		return null;
	}

	/**
	 * 
	 * @param d
	 * @return
	 */
	private static Date toDate(XMLGregorianCalendar d) {
		return (d == null) ? null : d.toGregorianCalendar().getTime();
	}

	public static LoadParameter toLoadParameter(LoanRequest request) {
		return new LoadParameter(request.getIdCard(), request.getName(),
				request.getSurname(), request.getCpkCode(),
				request.getCpsCode());
	}

	public static LoanType toSchema(Loan l) {
		com.sss.gsb.message.schemas.LoanType loanType = schemaTypeFactory
				.createLoanType();

		loanType.setHMEM(l.getCustomer().gethMem());
		loanType.setHTEACH(l.getCustomer().gethTaech());
		loanType.setCTYPE(l.getCustomer().getType());
		loanType.setFULLNAME(l.getCustomer().getFullname());
		loanType.setCIZID(l.getCustomer().getIdcard());

		loanType.setOPENDATE(toXMLGregorianCalendar(l.getOpenDate()));
		loanType.setSTAT(l.getStat());
		loanType.setFIRSTDFP(toXMLGregorianCalendar(l.getFirstDeposit()));
		loanType.setNEXTSCHND(toXMLGregorianCalendar(l.getNextSchedual()));
		loanType.setLASTCHLD(toXMLGregorianCalendar(l.getLastSchedual()));
		loanType.setPRINCIPAL(l.getPricipal());
		loanType.setBAL(l.getBalance());
		loanType.setBRCDNAME(l.getBranchName());
		loanType.setREGNAME(l.getRegionName());
		loanType.setDISTNAME(l.getDistrinctName());
		loanType.setMKTCDNAME(l.getProductMarketTypeName());
		loanType.setPROJCODE(l.getProjectCode());
		loanType.setPAYMENTDTNT(toXMLGregorianCalendar(l.getPaymentDate()));
		loanType.setPAMT(l.getPaymentAmount());
		loanType.setGTDUE(l.getGTDue());
		loanType.setOSEQ(l.getOSeq());
		loanType.setAMOMDT(toXMLGregorianCalendar(l.getAMOMDT()));
		loanType.setMAXOND(l.getMaxOND());
		loanType.setSIGNDTNT(toXMLGregorianCalendar(l.getSignDTNT()));
		loanType.setCLOSEDTNT(toXMLGregorianCalendar(l.getCloseDTNT()));

		if (l.getLoanAccountClosed() != null
				&& !l.getLoanAccountClosed().isEmpty()) {
			LoanAccountClosed lac = l.getLoanAccountClosed().iterator().next();
			loanType.setTRANDTNT(toXMLGregorianCalendar(lac
					.getTransactionDate()));
			loanType.setACCCLOSEBRCDNAME(lac.getBranchName());
			loanType.setEFFECTDTNT(toXMLGregorianCalendar(lac.getEffectDate()));
			loanType.setENDBAL(lac.getEndBalance());
			loanType.setTOTALAMT(lac.getTotalAmount());
			loanType.setPRIAMT(lac.getPrimaryAmount());
			loanType.setINTAMT(lac.getInterest());
			loanType.setPENAMT(lac.getPenaltyAmount());
			loanType.setTRANCODE(lac.getTransactionCode());
			loanType.setTRANTYPE(lac.getTransactionType());
			loanType.setLOANTRANCODE(lac.getLoanTransCode());
			loanType.setLOANTRANNAME(lac.getLoanTransName());
		}
		return loanType;
	}

	public static LoadParameter toLoadParameter(LoanAccountClosedRequest request) {
		return new LoadParameter(request.getIdCard(), request.getName(),
				request.getSurname(), request.getCpkCode(),
				request.getCpsCode());
	}

	public static LoanAccountClosedType toSchema(LoanAccountClosed lac) {

		com.sss.gsb.message.schemas.LoanAccountClosedType loanAcc = schemaTypeFactory
				.createLoanAccountClosedType();

		Customer c = lac.getLoan().getCustomer();
		Loan loan = lac.getLoan();

		loanAcc.setHMEM(c.gethMem());
		loanAcc.setHTEACH(c.gethTaech());
		loanAcc.setCTYPE(c.getType());
		loanAcc.setFULLNAME(c.getFullname());
		loanAcc.setCIZID(c.getIdcard());

		loanAcc.setOPENDATE(toXMLGregorianCalendar(loan.getOpenDate()));
		loanAcc.setSTAT(loan.getStat());
		loanAcc.setFIRSTDFP(toXMLGregorianCalendar(loan.getFirstDeposit()));
		loanAcc.setNEXTSCHND(toXMLGregorianCalendar(loan.getNextSchedual()));
		loanAcc.setLASTCHLD(toXMLGregorianCalendar(loan.getLastSchedual()));
		loanAcc.setPRINCIPAL(loan.getPricipal());
		loanAcc.setBAL(loan.getBalance());
		loanAcc.setBRCDNAME(loan.getBranchName());
		loanAcc.setREGNAME(loan.getRegionName());
		loanAcc.setDISTNAME(loan.getDistrinctName());
		loanAcc.setMKTCDNAME(loan.getProductMarketTypeName());
		loanAcc.setPROJCODE(loan.getProjectCode());
		loanAcc.setPAYMENTDTNT(toXMLGregorianCalendar(loan.getPaymentDate()));
		loanAcc.setPAMT(loan.getPaymentAmount());
		loanAcc.setGTDUE(loan.getGTDue());

		loanAcc.setAMOMDT(toXMLGregorianCalendar(loan.getAMOMDT()));
		loanAcc.setMAXOND(loan.getMaxOND());
		loanAcc.setSIGNDTNT(toXMLGregorianCalendar(loan.getSignDTNT()));
		return loanAcc;
	}

	public static LoadParameter toLoadParameter(BondsManRequest request) {
		return new LoadParameter(request.getIdCard(), request.getName(),
				request.getSurname(), request.getCpkCode(),
				request.getCpsCode());
	}

	public static BondsmanType toSchema(BondsMan bm) {
		com.sss.gsb.message.schemas.BondsmanType bondsman = schemaTypeFactory
				.createBondsmanType();

		Customer c = bm.getLoan().getCustomer();
		bondsman.setHMEM(c.gethMem());
		bondsman.setHTEACH(c.gethTaech());
		bondsman.setCTYPE(c.getType());
		bondsman.setFULLNAME(c.getFullname());
		bondsman.setCIZID(c.getIdcard());

		bondsman.setCID(bm.getLoan().getId().toBigInteger().intValue());
		bondsman.setORDERNO(bm.getOrderNo());
		bondsman.setBONDCIZID(bm.getBondIdCard());
		bondsman.setBONDFULLNAME(bm.getBondsFullname());
		bondsman.setBONDUNDERUNIT(bm.getBondUnderUnit());

		bondsman.setAADD(bm.getAddress());
		bondsman.setATAMBOL(bm.getRegisterTambol());
		bondsman.setACITY(bm.getAmphur1());
		bondsman.setASTATE(bm.getProvince1());
		bondsman.setAPROV(bm.getRegisterProvince());
		bondsman.setAZIP(bm.getZipcode());
		bondsman.setAHPH(bm.getHomePhoneNo());

		bondsman.setBADD(bm.getBusinessAddress());
		bondsman.setBOSDC(bm.getTambol2());
		bondsman.setBTAMBOL(bm.getBusinessTambol());
		bondsman.setBCITY(bm.getAmphur2());
		bondsman.setBAMPHUR(bm.getBusinessAmphurId());
		bondsman.setBSTATE(bm.getProvince2());
		bondsman.setBPROV(bm.getBusinessProvince());
		bondsman.setBZIP(bm.getBusinessZipcode());
		bondsman.setBWPH(bm.getWorkPhoneNo());
		bondsman.setBFAX(bm.getWorkFax());

		bondsman.setCADD(bm.getContactAddress());
		bondsman.setCMSDC(bm.getTambol3());
		bondsman.setCTAMBOL(bm.getContactTambol());
		bondsman.setCCITY(bm.getAmphur3());
		bondsman.setCAMPHUR(bm.getContactAmphur());
		bondsman.setCSTATE(bm.getProvince3());
		bondsman.setCPROV(bm.getContactProvince());
		bondsman.setCZIP(bm.getContactZipcode());
		bondsman.setCOPH(bm.getContactPhoneNo());

		return bondsman;
	}

	public static LoadParameter toLoadParameter(DeadmanRequest request) {
		return new LoadParameter(request.getIdCard(), request.getName(),
				request.getSurname(), request.getCpkCode(),
				request.getCpsCode());
	}

	public static DeadmanType toSchema(DeadMan dm) {
		com.sss.gsb.message.schemas.DeadmanType deadMan = schemaTypeFactory
				.createDeadmanType();
		Customer c = dm.getLoan().getCustomer();
		deadMan.setHMEM(c.gethMem());
		deadMan.setHTEACH(c.gethTaech());
		deadMan.setCTYPE(c.getType());
		deadMan.setFULLNAME(c.getFullname());
		deadMan.setCIZID(c.getIdcard());

		deadMan.setOPENDATE(toXMLGregorianCalendar(dm.getLoan().getOpenDate()));
		deadMan.setCID(dm.getId().intValue());
		deadMan.setDHTEACH(dm.gethTeach());
		deadMan.setDHMEM(dm.gethMem());
		deadMan.setDCTYPE(dm.getType());
		deadMan.setDTNAMESUR(dm.getFullName());
		deadMan.setDCIZID(dm.getIdCard());
		deadMan.setDAGE(dm.getAge());
		deadMan.setDDATEDATE(toXMLGregorianCalendar(dm.getDeadDate()));
		deadMan.setDPROVINCE(dm.getProvince());
		deadMan.setDDEADREASON(dm.getDeadReason());

		Loan loan = dm.getLoan();
		deadMan.setOPENDATE(toXMLGregorianCalendar(loan.getOpenDate()));
		deadMan.setSTAT(loan.getStat());
		deadMan.setFIRSTDFP(toXMLGregorianCalendar(loan.getFirstDeposit()));
		deadMan.setNEXTSCHND(toXMLGregorianCalendar(loan.getNextSchedual()));
		deadMan.setLASTCHLD(toXMLGregorianCalendar(loan.getLastSchedual()));
		deadMan.setPRINCIPAL(loan.getPricipal());
		deadMan.setBAL(loan.getBalance());
		deadMan.setBRCDNAME(loan.getBranchName());
		deadMan.setREGNAME(loan.getRegionName());
		deadMan.setDISTNAME(loan.getDistrinctName());
		deadMan.setMKTCDNAME(loan.getProductMarketTypeName());
		deadMan.setPROJCODE(loan.getProjectCode());
		deadMan.setPAYMENTDTNT(toXMLGregorianCalendar(loan.getPaymentDate()));
		deadMan.setPAMT(loan.getPaymentAmount());
		deadMan.setGTDUE(loan.getGTDue());

		return deadMan;
	}

	public static LoadParameter toLoadParameter(InsuranceRequest request) {
		return new LoadParameter(request.getIdCard(), request.getName(),
				request.getSurname(), request.getCpkCode(),
				request.getCpsCode());
	}

	public static InsuranceType toSchema(Insurance ins) {
		com.sss.gsb.message.schemas.InsuranceType insurance = schemaTypeFactory
				.createInsuranceType();

		Customer c = ins.getLoan().getCustomer();
		insurance.setHMEM(c.gethMem());
		insurance.setHTEACH(c.gethTaech());
		insurance.setCTYPE(c.getType());
		insurance.setFULLNAME(c.getFullname());
		insurance.setCIZID(c.getIdcard());

		insurance.setAPPLICATIONNO(ins.getApplicationNo());
		insurance.setBRCD(ins.getBranceId());
		insurance.setINSBRCDNAME(ins.getBranceName());
		insurance.setINSCODE(ins.getInsuranceAge());
		insurance
				.setINSBEGDTM(toXMLGregorianCalendar(ins.getInsuranceBegDtm()));
		insurance
				.setINSENDDTM(toXMLGregorianCalendar(ins.getInsuranceEndDtm()));
		insurance.setINSAGE(ins.getInsuranceAge());
		insurance.setINSAMT(ins.getInsuranceAmount());
		insurance.setINTERESTAMOUNT(ins.getInterestAmount());
		insurance.setTATALAMOUNT(ins.getTotalAmt());
		insurance.setRECEIVENO(ins.getReceiveNo());
		insurance.setRUNCODE(ins.getRunCode());

		Loan loan = ins.getLoan();
		insurance.setOPENDATE(toXMLGregorianCalendar(loan.getOpenDate()));
		insurance.setSTAT(loan.getStat());
		insurance.setFIRSTDFP(toXMLGregorianCalendar(loan.getFirstDeposit()));
		insurance.setNEXTSCHND(toXMLGregorianCalendar(loan.getNextSchedual()));
		insurance.setLASTCHLD(toXMLGregorianCalendar(loan.getLastSchedual()));
		insurance.setPRINCIPAL(loan.getPricipal());
		insurance.setBAL(loan.getBalance());
		insurance.setBRCDNAME(loan.getBranchName());
		insurance.setREGNAME(loan.getRegionName());
		insurance.setDISTNAME(loan.getDistrinctName());
		insurance.setMKTCDNAME(loan.getProductMarketTypeName());
		insurance.setPROJCODE(loan.getProjectCode());
		insurance.setPAYMENTDTNT(toXMLGregorianCalendar(loan.getPaymentDate()));
		insurance.setPAMT(loan.getPaymentAmount());
		insurance.setGTDUE(loan.getGTDue());

		return insurance;
	}

	public static RowModel toGridModel(Integer total, BondsmanType bm) {

		return new RowModel(total + 1, bm.getHTEACH(), bm.getHMEM(),
				bm.getCIZID(), bm.getFULLNAME());
	}

	public static RowModel toGridModel(Integer total, DeadmanType dm) {
		return new RowModel(total + 1, dm.getHTEACH(), dm.getHMEM(),
				dm.getCIZID(), dm.getFULLNAME());
	}

	public static RowModel toGridModel(Integer total, InsuranceType ins) {
		return new RowModel(total + 1, ins.getHTEACH(), ins.getHMEM(),
				ins.getCIZID(), ins.getFULLNAME());
	}

//	@Deprecated
//	public static LoanAccountClosedRow toGridModel(Integer total,
//			LoanAccountClosedType lac) {
//		return new LoanAccountClosedRow(total + 1, lac.getCIZID(),
//				lac.getFULLNAME());
//	}

	public static RowModel toGridModel(Integer total, LoanType l) {
		return new RowModel(total + 1, l.getHTEACH(), l.getHMEM(),
				l.getCIZID(), l.getFULLNAME());
	}

}
